import React, { useState } from 'react';
import {
  FileCode,
  FileSymlink,
  FolderPlus,
  FileX,
  Replace,
  CheckCircle,
  AlertTriangle,
  ExternalLink,
  CircleDashed,
  Code,
  Eye,
  FileSpreadsheet,
} from 'lucide-react';
import { ToolViewProps } from './types';
import {
  extractFilePath,
  extractFileContent,
  getFileType,
  formatTimestamp,
  getToolTitle,
} from './utils';
import { GenericToolView } from './GenericToolView';
import {
  MarkdownRenderer,
  processUnicodeContent,
} from '@/components/file-renderers/markdown-renderer';
import { CsvRenderer } from '@/components/file-renderers/csv-renderer';
import { cn } from '@/lib/utils';
import { useTheme } from 'next-themes';
import { CodeBlockCode } from '@/components/ui/code-block';
import { constructHtmlPreviewUrl } from '@/lib/utils/url';

// Type for operation type
type FileOperation = 'create' | 'rewrite' | 'delete';

// Map file extensions to language names for syntax highlighting
const getLanguageFromFileName = (fileName: string): string => {
  const extension = fileName.split('.').pop()?.toLowerCase() || '';

  // Map of file extensions to language names for syntax highlighting
  const extensionMap: Record<string, string> = {
    // Web languages
    html: 'html',
    htm: 'html',
    css: 'css',
    scss: 'scss',
    sass: 'scss',
    less: 'less',
    js: 'javascript',
    jsx: 'jsx',
    ts: 'typescript',
    tsx: 'tsx',
    json: 'json',
    jsonc: 'json',

    // Build and config files
    xml: 'xml',
    yml: 'yaml',
    yaml: 'yaml',
    toml: 'toml',
    ini: 'ini',
    env: 'bash',
    gitignore: 'bash',
    dockerignore: 'bash',

    // Scripting languages
    py: 'python',
    rb: 'ruby',
    php: 'php',
    go: 'go',
    java: 'java',
    kt: 'kotlin',
    c: 'c',
    cpp: 'cpp',
    h: 'c',
    hpp: 'cpp',
    cs: 'csharp',
    swift: 'swift',
    rs: 'rust',

    // Shell scripts
    sh: 'bash',
    bash: 'bash',
    zsh: 'bash',
    ps1: 'powershell',
    bat: 'batch',
    cmd: 'batch',

    // Markup languages (excluding markdown which has its own renderer)
    svg: 'svg',
    tex: 'latex',

    // Data formats
    graphql: 'graphql',
    gql: 'graphql',
  };

  return extensionMap[extension] || 'text';
};

export function FileOperationToolView({
  assistantContent,
  toolContent,
  assistantTimestamp,
  toolTimestamp,
  isSuccess = true,
  isStreaming = false,
  name,
  project,
}: ToolViewProps) {
  const { resolvedTheme } = useTheme();
  const isDarkTheme = resolvedTheme === 'dark';

  // Determine operation type from content or name
  const getOperationType = (): FileOperation => {
    // First check tool name if available
    if (name) {
      if (name.includes('create')) return 'create';
      if (name.includes('rewrite')) return 'rewrite';
      if (name.includes('delete')) return 'delete';
    }

    if (!assistantContent) return 'create'; // default fallback

    if (assistantContent.includes('<create-file>')) return 'create';
    if (assistantContent.includes('<full-file-rewrite>')) return 'rewrite';
    if (
      assistantContent.includes('delete-file') ||
      assistantContent.includes('<delete>')
    )
      return 'delete';

    // Check for tool names as a fallback
    if (assistantContent.toLowerCase().includes('create file')) return 'create';
    if (assistantContent.toLowerCase().includes('rewrite file'))
      return 'rewrite';
    if (assistantContent.toLowerCase().includes('delete file')) return 'delete';

    // Default to create if we can't determine
    return 'create';
  };

  const operation = getOperationType();
  const filePath = extractFilePath(assistantContent);
  const toolTitle = getToolTitle(name || `file-${operation}`);

  // Only extract content for create and rewrite operations
  const fileContent =
    operation !== 'delete'
      ? extractFileContent(
          assistantContent,
          operation === 'create' ? 'create-file' : 'full-file-rewrite',
        )
      : null;

  // For debugging - show raw content if file path can't be extracted for delete operations
  const showDebugInfo = !filePath && operation === 'delete';

  // Process file path - handle potential newlines and clean up
  const processedFilePath = filePath
    ? filePath.trim().replace(/\\n/g, '\n').split('\n')[0]
    : null;

  // For create and rewrite, prepare content for display
  const contentLines = fileContent
    ? fileContent.replace(/\\n/g, '\n').split('\n')
    : [];
  const fileName = processedFilePath
    ? processedFilePath.split('/').pop() || processedFilePath
    : '';
  const fileType = processedFilePath ? getFileType(processedFilePath) : '';
  const isMarkdown = fileName.endsWith('.md');
  const isHtml = fileName.endsWith('.html');
  const isCsv = fileName.endsWith('.csv');
  const language = getLanguageFromFileName(fileName);
  const hasHighlighting = language !== 'text';
  // Construct HTML file preview URL if we have a sandbox and the file is HTML
  const htmlPreviewUrl =
    isHtml && project?.sandbox?.sandbox_url && processedFilePath
      ? constructHtmlPreviewUrl(project.sandbox.sandbox_url, processedFilePath)
      : undefined;

  console.log('HTML Preview URL:', htmlPreviewUrl);
  // Add state for view mode toggle (code or preview)
  const [viewMode, setViewMode] = useState<'code' | 'preview'>(
    isHtml || isMarkdown || isCsv ? 'preview' : 'code',
  );

  // Fall back to generic view if file path is missing or if content is missing for non-delete operations
  if (
    (!filePath && !showDebugInfo) ||
    (operation !== 'delete' && !fileContent)
  ) {
    return (
      <GenericToolView
        name={name || `file-${operation}`}
        assistantContent={assistantContent}
        toolContent={toolContent}
        assistantTimestamp={assistantTimestamp}
        toolTimestamp={toolTimestamp}
        isSuccess={isSuccess}
        isStreaming={isStreaming}
      />
    );
  }

  // Operation-specific configs
  const configs = {
    create: {
      icon: FolderPlus,
      successMessage: 'File created successfully',
    },
    rewrite: {
      icon: Replace,
      successMessage: 'File rewritten successfully',
    },
    delete: {
      icon: FileX,
      successMessage: 'File deleted successfully',
    },
  };

  const config = configs[operation];
  const Icon = config.icon;

  return (
    <div className="flex flex-col h-full">
      <div className="flex-1 p-4 overflow-auto">
        {/* File Content for create and rewrite operations */}
        {operation !== 'delete' && fileContent && !isStreaming && (
          <div className="border border-zinc-200 dark:border-zinc-800 rounded-md overflow-hidden shadow-sm bg-white dark:bg-zinc-950 h-full flex flex-col">
            {/* IDE Header */}
            <div className="flex items-center p-2 bg-zinc-100 dark:bg-zinc-900 text-zinc-900 dark:text-zinc-100 justify-between border-b border-zinc-200 dark:border-zinc-800">
              <div className="flex items-center">
                {isMarkdown ? (
                  <FileCode className="h-4 w-4 mr-2 text-zinc-600 dark:text-zinc-400" />
                ) : isCsv ? (
                  <FileSpreadsheet className="h-4 w-4 mr-2 text-zinc-600 dark:text-zinc-400" />
                ) : (
                  <FileSymlink className="h-4 w-4 mr-2 text-zinc-600 dark:text-zinc-400" />
                )}
                <span className="text-xs font-medium">{fileName}</span>
              </div>

              <div className="flex items-center gap-2">
                {/* View switcher for HTML files */}
                {isHtml && htmlPreviewUrl && isSuccess && (
                  <div className="flex rounded-md overflow-hidden border border-zinc-200 dark:border-zinc-700">
                    <button
                      onClick={() => setViewMode('code')}
                      className={cn(
                        'flex items-center gap-1 text-xs px-2 py-1 transition-colors',
                        viewMode === 'code'
                          ? 'bg-zinc-800 text-zinc-100 dark:bg-zinc-700 dark:text-zinc-100'
                          : 'bg-zinc-200 text-zinc-700 dark:bg-zinc-800 dark:text-zinc-400 hover:bg-zinc-300 dark:hover:bg-zinc-700',
                      )}
                    >
                      <Code className="h-3 w-3" />
                      <span>Code</span>
                    </button>
                    <button
                      onClick={() => setViewMode('preview')}
                      className={cn(
                        'flex items-center gap-1 text-xs px-2 py-1 transition-colors',
                        viewMode === 'preview'
                          ? 'bg-zinc-800 text-zinc-100 dark:bg-zinc-700 dark:text-zinc-100'
                          : 'bg-zinc-200 text-zinc-700 dark:bg-zinc-800 dark:text-zinc-400 hover:bg-zinc-300 dark:hover:bg-zinc-700',
                      )}
                    >
                      <Eye className="h-3 w-3" />
                      <span>Preview</span>
                    </button>
                  </div>
                )}
                {/* View switcher for Markdown files */}
                {isMarkdown && isSuccess && (
                  <div className="flex rounded-md overflow-hidden border border-zinc-200 dark:border-zinc-700">
                    <button
                      onClick={() => setViewMode('code')}
                      className={cn(
                        'flex items-center gap-1 text-xs px-2 py-1 transition-colors',
                        viewMode === 'code'
                          ? 'bg-zinc-800 text-zinc-100 dark:bg-zinc-700 dark:text-zinc-100'
                          : 'bg-zinc-200 text-zinc-700 dark:bg-zinc-800 dark:text-zinc-400 hover:bg-zinc-300 dark:hover:bg-zinc-700',
                      )}
                    >
                      <Code className="h-3 w-3" />
                      <span>Code</span>
                    </button>
                    <button
                      onClick={() => setViewMode('preview')}
                      className={cn(
                        'flex items-center gap-1 text-xs px-2 py-1 transition-colors',
                        viewMode === 'preview'
                          ? 'bg-zinc-800 text-zinc-100 dark:bg-zinc-700 dark:text-zinc-100'
                          : 'bg-zinc-200 text-zinc-700 dark:bg-zinc-800 dark:text-zinc-400 hover:bg-zinc-300 dark:hover:bg-zinc-700',
                      )}
                    >
                      <Eye className="h-3 w-3" />
                      <span>Preview</span>
                    </button>
                  </div>
                )}
                {/* View switcher for CSV files */}
                {isCsv && isSuccess && (
                  <div className="flex rounded-md overflow-hidden border border-zinc-200 dark:border-zinc-700">
                    <button
                      onClick={() => setViewMode('code')}
                      className={cn(
                        'flex items-center gap-1 text-xs px-2 py-1 transition-colors',
                        viewMode === 'code'
                          ? 'bg-zinc-800 text-zinc-100 dark:bg-zinc-700 dark:text-zinc-100'
                          : 'bg-zinc-200 text-zinc-700 dark:bg-zinc-800 dark:text-zinc-400 hover:bg-zinc-300 dark:hover:bg-zinc-700',
                      )}
                    >
                      <Code className="h-3 w-3" />
                      <span>Code</span>
                    </button>
                    <button
                      onClick={() => setViewMode('preview')}
                      className={cn(
                        'flex items-center gap-1 text-xs px-2 py-1 transition-colors',
                        viewMode === 'preview'
                          ? 'bg-zinc-800 text-zinc-100 dark:bg-zinc-700 dark:text-zinc-100'
                          : 'bg-zinc-200 text-zinc-700 dark:bg-zinc-800 dark:text-zinc-400 hover:bg-zinc-300 dark:hover:bg-zinc-700',
                      )}
                    >
                      <Eye className="h-3 w-3" />
                      <span>Preview</span>
                    </button>
                  </div>
                )}
                <span className="text-xs text-zinc-500 dark:text-zinc-400 bg-zinc-200 dark:bg-zinc-800 px-2 py-0.5 rounded">
                  {hasHighlighting ? language.toUpperCase() : fileType}
                </span>
              </div>
            </div>

            {/* File Content (Code View with Syntax Highlighting) */}
            {viewMode === 'code' ||
            (!isHtml && !isMarkdown && !isCsv) ||
            !isSuccess ? (
              <div className="flex-1 overflow-auto bg-white dark:bg-zinc-950 text-zinc-900 dark:text-zinc-100">
                {hasHighlighting ? (
                  <div className="relative">
                    <div className="absolute left-0 top-0 bottom-0 w-12 border-r border-zinc-200 dark:border-zinc-800 z-10 flex flex-col">
                      {contentLines.map((_, idx) => (
                        <div
                          key={idx}
                          className="h-6 text-right pr-3 text-xs font-mono text-zinc-500 dark:text-zinc-500 select-none"
                        >
                          {idx + 1}
                        </div>
                      ))}
                    </div>
                    <div className="pl-12">
                      <CodeBlockCode
                        code={processUnicodeContent(fileContent)}
                        language={language}
                        className="text-xs p-2"
                      />
                    </div>
                  </div>
                ) : (
                  <div className="min-w-full table">
                    {contentLines.map((line, idx) => (
                      <div
                        key={idx}
                        className="table-row hover:bg-zinc-50 dark:hover:bg-zinc-900 transition-colors"
                      >
                        <div className="table-cell text-right pr-3 py-0.5 text-xs font-mono text-zinc-500 dark:text-zinc-500 select-none w-12 border-r border-zinc-200 dark:border-zinc-800">
                          {idx + 1}
                        </div>
                        <div className="table-cell pl-3 py-0.5 text-xs font-mono whitespace-pre text-zinc-800 dark:text-zinc-300">
                          {processUnicodeContent(line) || ' '}
                        </div>
                      </div>
                    ))}
                    <div className="table-row h-4"></div>
                  </div>
                )}
              </div>
            ) : null}

            {/* HTML Preview with iframe */}
            {isHtml &&
              viewMode === 'preview' &&
              htmlPreviewUrl &&
              isSuccess && (
                <div className="flex-1 bg-white overflow-hidden">
                  <iframe
                    src={htmlPreviewUrl}
                    title={`HTML Preview of ${fileName}`}
                    className="w-full h-full border-0"
                    style={{ minHeight: '300px' }}
                    sandbox="allow-same-origin allow-scripts"
                  />
                </div>
              )}

            {/* Markdown Preview */}
            {isMarkdown && viewMode === 'preview' && isSuccess && (
              <div className="flex-1 overflow-auto bg-white dark:bg-zinc-950 text-zinc-900 dark:text-zinc-100">
                <MarkdownRenderer
                  content={processUnicodeContent(fileContent)}
                />
              </div>
            )}

            {/* CSV Preview */}
            {isCsv && viewMode === 'preview' && isSuccess && (
              <div className="flex-1 overflow-hidden bg-white dark:bg-zinc-950">
                <CsvRenderer content={processUnicodeContent(fileContent)} />
              </div>
            )}

            {/* External link button for HTML files */}
            {isHtml &&
              viewMode === 'preview' &&
              htmlPreviewUrl &&
              isSuccess && (
                <div className="bg-zinc-100 dark:bg-zinc-900 p-2 border-t border-zinc-200 dark:border-zinc-800 flex justify-end">
                  <a
                    href={htmlPreviewUrl}
                    target="_blank"
                    rel="noopener noreferrer"
                    className="flex items-center gap-1.5 py-1 px-2 text-xs text-zinc-700 dark:text-zinc-300 bg-zinc-200 dark:bg-zinc-800 hover:bg-zinc-300 dark:hover:bg-zinc-700 rounded transition-colors"
                  >
                    <ExternalLink className="h-3.5 w-3.5 text-zinc-500 flex-shrink-0" />
                    <span>Open in Browser</span>
                  </a>
                </div>
              )}
          </div>
        )}

        {/* File Content for streaming state */}
        {operation !== 'delete' && isStreaming && (
          <div className="border border-zinc-200 dark:border-zinc-800 rounded-md overflow-hidden shadow-sm bg-white dark:bg-zinc-950 h-full flex flex-col">
            {/* IDE Header */}
            <div className="flex items-center p-2 bg-zinc-100 dark:bg-zinc-900 text-zinc-900 dark:text-zinc-100 justify-between border-b border-zinc-200 dark:border-zinc-800">
              <div className="flex items-center">
                <FileSymlink className="h-4 w-4 mr-2 text-zinc-600 dark:text-zinc-400" />
                <span className="text-xs font-medium">
                  {fileName || 'file.txt'}
                </span>
              </div>
              <span className="text-xs text-zinc-500 dark:text-zinc-400 bg-zinc-200 dark:bg-zinc-800 px-2 py-0.5 rounded">
                {fileType || 'Text'}
              </span>
            </div>

            {/* Streaming state */}
            <div className="flex-1 flex items-center justify-center p-8 bg-white dark:bg-zinc-950">
              <div className="text-center">
                <CircleDashed className="h-8 w-8 mx-auto mb-3 text-blue-500 animate-spin" />
                <p className="text-sm font-medium text-zinc-700 dark:text-zinc-300">
                  {operation === 'create'
                    ? 'Creating file...'
                    : 'Rewriting file...'}
                </p>
                <p className="text-xs mt-1 text-zinc-500 dark:text-zinc-400">
                  {processedFilePath || 'Processing file operation'}
                </p>
              </div>
            </div>
          </div>
        )}

        {/* Delete view with file path */}
        {operation === 'delete' && processedFilePath && !isStreaming && (
          <div className="border border-zinc-200 dark:border-zinc-800 rounded-md overflow-hidden h-full flex flex-col">
            <div className="p-6 flex-1 flex flex-col items-center justify-center bg-white dark:bg-zinc-950 text-zinc-900 dark:text-zinc-100">
              <div className="w-14 h-14 rounded-full bg-red-50 dark:bg-red-900/20 flex items-center justify-center mb-4">
                <FileX className="h-7 w-7 text-red-600 dark:text-red-400" />
              </div>
              <h3 className="text-lg font-medium mb-4 text-red-600 dark:text-red-400">
                File Deleted
              </h3>
              <div className="bg-zinc-50 dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 rounded-md p-4 w-full max-w-md text-center mb-2">
                <code className="text-sm font-mono text-zinc-700 dark:text-zinc-300 break-all">
                  {processedFilePath}
                </code>
              </div>
              <p className="text-sm text-zinc-500 dark:text-zinc-400 mt-2">
                This file has been permanently removed
              </p>
            </div>
          </div>
        )}

        {/* Delete view streaming state */}
        {operation === 'delete' && isStreaming && (
          <div className="border border-zinc-200 dark:border-zinc-800 rounded-md overflow-hidden h-full flex flex-col">
            <div className="p-6 flex-1 flex flex-col items-center justify-center bg-white dark:bg-zinc-950">
              <div className="text-center">
                <CircleDashed className="h-8 w-8 mx-auto mb-3 text-blue-500 animate-spin" />
                <p className="text-sm font-medium text-zinc-700 dark:text-zinc-300">
                  Deleting file...
                </p>
                {processedFilePath && (
                  <p className="text-xs mt-2 font-mono text-zinc-500 dark:text-zinc-400 break-all">
                    {processedFilePath}
                  </p>
                )}
              </div>
            </div>
          </div>
        )}

        {/* Delete view with unknown path */}
        {operation === 'delete' &&
          !processedFilePath &&
          !showDebugInfo &&
          !isStreaming && (
            <div className="border border-zinc-200 dark:border-zinc-800 rounded-md overflow-hidden h-full flex flex-col">
              <div className="p-6 flex-1 flex flex-col items-center justify-center bg-white dark:bg-zinc-950 text-zinc-900 dark:text-zinc-100">
                <div className="w-14 h-14 rounded-full bg-red-50 dark:bg-red-900/20 flex items-center justify-center mb-4">
                  <FileX className="h-7 w-7 text-red-600 dark:text-red-400" />
                </div>
                <h3 className="text-lg font-medium mb-4 text-red-600 dark:text-red-400">
                  File Deleted
                </h3>
                <div className="bg-zinc-50 dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 rounded-md p-4 w-full max-w-md text-center mb-2">
                  <p className="text-sm text-zinc-700 dark:text-zinc-300">
                    Unknown file path
                  </p>
                </div>
                <p className="text-sm text-zinc-500 dark:text-zinc-400 mt-2">
                  A file has been deleted but the path could not be determined
                </p>
              </div>
            </div>
          )}
      </div>

      {/* Footer */}
      <div className="p-4 border-t border-zinc-200 dark:border-zinc-800">
        <div className="flex items-center justify-between text-xs text-zinc-500 dark:text-zinc-400">
          {!isStreaming && (
            <div className="flex items-center gap-2">
              {isSuccess ? (
                <CheckCircle className="h-3.5 w-3.5 text-emerald-500" />
              ) : (
                <AlertTriangle className="h-3.5 w-3.5 text-red-500" />
              )}
              <span>
                {isSuccess
                  ? config.successMessage
                  : `Failed to ${operation} file`}
              </span>
            </div>
          )}

          {isStreaming && (
            <div className="flex items-center gap-2">
              <CircleDashed className="h-3.5 w-3.5 text-blue-500 animate-spin" />
              <span>Processing file operation...</span>
            </div>
          )}

          <div className="text-xs">
            {toolTimestamp && !isStreaming
              ? formatTimestamp(toolTimestamp)
              : assistantTimestamp
                ? formatTimestamp(assistantTimestamp)
                : ''}
          </div>
        </div>
      </div>
    </div>
  );
}
